package net.wanderinghorse.jsonmessage.poster;

import net.wanderinghorse.jsonmessage.*;

/**
 * An RequestPoster implementation uses ResponseHandlerLoader to load local responses
 * and dispatch them as if they came in via a remote connection.
 */
public class LocalRequestPoster extends AbstractRequestPoster {
    /**
     * Tries to find a local ResponseHandler for the given request and pass off request
     * to that handler.
     *
     * This function uses loadRequestHandler() to find a ResponseHandler instance to process
     * the response.
     *
     * A note about how the various post callbacks are used:
     *
     * This implementation will always call the onResponse() callback because...
     * onError() is used to signal connection-level errors. Since this is a local
     * instance, there is no connection which can fail. Thus, in the face of response errors
     * this type behaves like a remote-posting implementation would: it calls
     * onResponse(), passing the error information. This is arguably unintuitive,
     * but is for consistency with framework conventions and related implementations.
     *
     * @param r The request to post.
     * @param opt This object is ignored by this function but is passed to the various
     * callbacks, so it should not be null.
     */
    @Override
    protected final void doPost(final Request r, final PostOptions opt) throws Exception {
        final String key = r.getType();
        RequestHandler hnd = this.loadRequestHandler( key );
        Response rsp = new Response();
        rsp.setRequestId( r.getId() );
        rsp.setType( r.getType() );
        if( (null == hnd) ) {
            final int err = Response.ErrTypes.NO_RESPONSE_FOUND.getValue();
            rsp.setErrorInfo( err, err, "No responder found for message type ["+r.getType()+"]" );
        }
        else {
            try {
                hnd.processResponse(r, rsp);
            }
            catch( Exception ex ) {
                final int err = Response.ErrTypes.RESPONSE_THREW.getValue();
                rsp.setErrorInfo( err, err,
                                  "Exception ("+ex.getClass().getName()+") while processing response: "
                                  +ex.toString() );
            }
        }
        this.onResponse( r, rsp, opt );
    }

}
